﻿using System.Collections.Generic;
using UnityEngine;

namespace UnityView
{
    public class AdapterCellHolder
    {
        // 当前持有的cell的索引数
        public int Index;
        public IViewLayout View;
        public Vector2 Position;

        public void Update(IViewLayout view, int index, Vector2 position)
        {
            View = view;
            Index = index;
            Position = position;
            RectTransform transform = view.RectTransform;
            transform.anchoredPosition = position;
        }

        public void Update(IViewLayout view, int index, Vector2 position, Vector2 size)
        {
            View = view;
            Index = index;
            Position = position;
            RectTransform transform = view.RectTransform;
            transform.gameObject.SetActive(true);
            transform.anchoredPosition = position;
            transform.sizeDelta = size;
        }
    }

    /// <summary>
    /// 存储AdapterView中Cell的结构
    /// </summary>
    public class AdapterCellCache
    {
        /// <summary>
        /// 循环队列存储CellHolder
        /// </summary>
        public readonly CircleLinkedList<AdapterCellHolder> CellHolders;

        /// <summary>
        /// 记录当前的起始索引
        /// </summary>
        protected int CachedStartIndex = 0;

        protected int CachedVisibleCount = 0;

        public AdapterCellCache()
        {
            CellHolders = new CircleLinkedList<AdapterCellHolder>(12);
            var node = CellHolders.CurrentNode;
            for (int i = 0; i < 12; i++)
            {
                node.Value = new AdapterCellHolder();
                node = node.Next;
            }
        }

        public AdapterCellHolder this[int index]
        {
            get
            {
                if (index < CachedStartIndex) return null;
                // if (index >= StartIndex + CellHolders.Count) return null;
                var head = CellHolders.CurrentNode;
                if (head == null) return null;
                for (int i = 0; i < index - CachedStartIndex; i++)
                {
                    head = head.Next;
                    if (head == null) return null;
                }
                return head.Value;
            }
        }

        public struct InquireInfo
        {
            public LinkedNode<AdapterCellHolder> Node;
            public int DirtyIndex;
            public int DirtyCount;

            public InquireInfo(LinkedNode<AdapterCellHolder> node, int dirtyIndex, int dirtyCount)
            {
                Node = node;
                DirtyIndex = dirtyIndex;
                DirtyCount = dirtyCount;
            }
        }

        public void Reset()
        {
            CachedStartIndex = 0;
            CachedVisibleCount = 0;
            CellHolders.Tail = CellHolders.Head;
        }

        public InquireInfo Inquire(int startIndex, int count)
        {
            // 保证holder的总数要满足可见cell的数量要求
            if (count > CellHolders.Count)
            {
                int newCount = count - CellHolders.Count;
                CellHolders.Count = count;
                var node = CellHolders.CurrentNode.Previous;
                for (int i = 0; i < newCount; i++)
                {
                    node.Value = new AdapterCellHolder();
                    node = node.Previous;
                }
            }

            int headStep = startIndex - CachedStartIndex;
            CellHolders.MoveHead(headStep);

            LinkedNode<AdapterCellHolder> targetNode;
            int dirtyIndex;
            int dirtyCount;

            if (headStep >= 0)
            {
                int reuseCount = CachedStartIndex + CachedVisibleCount - startIndex;
                if (reuseCount < 0) reuseCount = 0;
                dirtyCount = count - reuseCount;
                dirtyIndex = startIndex + count - dirtyCount;

                // tailStep可能小于0
                int tailStep = (startIndex + count) - (CachedStartIndex + CachedVisibleCount);
                // Debug.Log($"startIndex: {startIndex}, count: {count}, CachedStartIndex: {CachedStartIndex}, CachedVisibleCount: {CachedVisibleCount}");
                // Debug.Log($"move tail {tailStep}");
                // Debug.Log($"tail index: {CellHolders.Tail.Index}");

                targetNode = CellHolders.Tail;
                CellHolders.MoveTail(tailStep);
            }
            else
            {
                int reuseCount = startIndex + count - CachedStartIndex;
                if (reuseCount < 0) reuseCount = 0;
                dirtyCount = count - reuseCount;
                dirtyIndex = startIndex;
                targetNode = CellHolders.Head;
                
                // tailStep可能小于0
                int tailStep = (startIndex + count) - (CachedStartIndex + CachedVisibleCount);
                CellHolders.MoveTail(tailStep);

            }

            CachedStartIndex = startIndex;
            CachedVisibleCount = count;

            return new InquireInfo(targetNode, dirtyIndex, dirtyCount);
        }

        public void Clear()
        {
            var node = CellHolders.Tail;
            while (node != CellHolders.Head)
            {
                node.Value.View.RectTransform.gameObject.SetActive(false);
                node = node.Next;
            }
        }
    }

    public class AdapterCellCache<T> where T : AdapterCellHolder, new()
    {
        public readonly List<T> Objects = new List<T>();

        public T Dequeue()
        {
            T cell = null;
            if (Objects.Count > 0)
            {
                cell = Objects[0];
                cell.View.RectTransform.gameObject.SetActive(true);
                Objects.RemoveAt(0);
            }
            else
            {
                cell = new T();
            }
            return cell;
        }

        public void Enqueue(T cell)
        {
            cell.View.RectTransform.gameObject.SetActive(false);
            Objects.Add(cell);
        }
    }
}